/**
 * 
 */
package de.cbf.cam.dsa.tavern.carte.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import de.cbf.cam.dsa.tavern.carte.model.entities.Ingredient;
import de.cbf.cam.dsa.tavern.carte.ui.listeners.EnterPositiveDoubleForEvent;


/**
 * @author Stefan Alter
 *
 */
public class CompositeIngredient extends Composite {

	private Label staticName			= null;
	private Label staticParent			= null;
	private Label staticCategories		= null;
	private Label staticDescription		= null;
	private Label staticPrice			= null;
	private Button checkBoxIngredient	= null;
	private Button checkBoxCategory		= null;
	private Text textName				= null;	
	private Text textParent				= null;	
	private Text textCategories			= null;	
	private Text textDescription		= null;	
	private Text textPrice				= null;

	/**
	 * @param parent
	 * @param style
	 */
	public CompositeIngredient(Composite parent, int style) {
		super(parent, style);
		initialize();		
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
		//FIXME needs overhaul in naming and looks
        GridData gridData12 = new GridData();
        gridData12.horizontalAlignment = GridData.BEGINNING;
        gridData12.verticalAlignment = GridData.FILL;
        GridData gridData41 = new GridData();
        gridData41.horizontalAlignment = GridData.FILL;
        gridData41.verticalAlignment = GridData.CENTER;
        GridData gridData31 = new GridData();
        gridData31.verticalAlignment = GridData.CENTER;
        gridData31.horizontalAlignment = GridData.END;
        GridData gridData21 = new GridData();
        gridData21.horizontalSpan = 3;
        gridData21.verticalAlignment = GridData.FILL;
        gridData21.grabExcessHorizontalSpace = true;
        gridData21.grabExcessVerticalSpace = true;
        gridData21.horizontalAlignment = GridData.FILL;
        GridData gridData11 = new GridData();
        GridData gridData4 = new GridData();
        gridData4.horizontalAlignment = GridData.FILL;
        gridData4.grabExcessHorizontalSpace = true;
        gridData4.verticalAlignment = GridData.CENTER;
        GridData gridData3 = new GridData();
        gridData3.verticalAlignment = GridData.CENTER;
        gridData3.grabExcessHorizontalSpace = true;
        gridData3.horizontalSpan = 2;
        gridData3.horizontalAlignment = GridData.FILL;
        GridData gridData2 = new GridData();
        GridData gridData1 = new GridData();
        gridData1.verticalAlignment = GridData.CENTER;
        gridData1.horizontalAlignment = GridData.FILL;
        GridData gridData = new GridData();
        gridData.verticalAlignment = GridData.FILL;
        gridData.horizontalAlignment = GridData.BEGINNING;
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        gridLayout.verticalSpacing = 0;
        gridLayout.marginWidth = 0;
        gridLayout.marginHeight = 0;
        gridLayout.horizontalSpacing = 2;
        staticName = new Label(this, SWT.NONE);
        staticName.setText("Name: ");
        textName = new Text(this, SWT.BORDER);
        textName.setLayoutData(gridData1);
        checkBoxIngredient = new Button(this, SWT.CHECK);
        checkBoxIngredient.setText("Zutat");
        checkBoxIngredient.setLayoutData(gridData);
        staticParent = new Label(this, SWT.NONE);
        staticParent.setText("Zutatengruppe: ");
        staticParent.setLayoutData(gridData2);
        textParent = new Text(this, SWT.BORDER | SWT.READ_ONLY);
        textParent.setLayoutData(gridData4);
        checkBoxCategory = new Button(this, SWT.CHECK);
        checkBoxCategory.setText("Kategorie");
        checkBoxCategory.setLayoutData(gridData12);
        staticCategories = new Label(this, SWT.NONE);
        staticCategories.setText("Kategorien: ");
        textCategories = new Text(this, SWT.BORDER | SWT.READ_ONLY);
        textCategories.setLayoutData(gridData3);
        staticDescription = new Label(this, SWT.NONE);
        staticDescription.setText("Beschreibung:");
        staticDescription.setLayoutData(gridData11);
        staticPrice = new Label(this, SWT.NONE);
        staticPrice.setText("Preis:");
        staticPrice.setLayoutData(gridData31);
       
        textPrice = new Text(this, SWT.BORDER);
        textPrice.setLayoutData(gridData41);
      
        textDescription = new Text(this,SWT.BORDER| SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
        textDescription.setLayoutData(gridData21);
        this.setLayout(gridLayout);
        //
        registerListeners(); 
        //        
//        textCategories.setEditable(false);
//        textParent.setEditable(false);
	}

	private void registerListeners() {
		checkBoxCategory.addSelectionListener(isCategoryChanged);
		checkBoxIngredient.addSelectionListener(isIngredientChanged);
		textName.addModifyListener(nameModified);
		textParent.addKeyListener(removeParent);
		textCategories.addKeyListener(removeLastCategory);
		textDescription.addModifyListener(descriptionModified);
		EnterPositiveDoubleForEvent.addToText(textPrice, priceModifiedListeners);
	}
	public void clearData() {
		textName.setText("");
		textParent.setText("");
		textCategories.setText("");
		textDescription.setText("");
		textPrice.setText("");
		checkBoxCategory.setSelection(false);
		checkBoxIngredient.setSelection(false);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
	 */
	@Override
	public void setEnabled(boolean enabled) {
		textName.setEnabled(enabled);
		textParent.setEnabled(enabled);
		textCategories.setEnabled(enabled);
		textDescription.setEnabled(enabled);
		textPrice.setEnabled(enabled);
		if(enabled){
			textPrice.setBackground(ColorShorts.white);
		}else{
			textPrice.setBackground(ColorShorts.backGround);
		}
		checkBoxCategory.setEnabled(enabled);
		checkBoxIngredient.setEnabled(enabled);
	}

	public String getIngredientName(){
		return textName.getText();
	}
	public void setIngredientName(String name){
		if(getIngredientName().equals(name))return;
		Point index = textName.getSelection();
		textName.setText(name);
		textName.setSelection(index); //place cursor at end for normal entering 
	}
	public boolean getIsIngredient(){
		return checkBoxIngredient.getSelection();
	}
	public void setIsIngredient(boolean value){
		if(getIsIngredient() == value)return;
		checkBoxIngredient.setSelection(value);
	}
	public boolean getIsCategory(){
		return checkBoxCategory.getSelection();
	}
	public void setIsCategory(boolean value){
		if(getIsCategory() == value)return;
		checkBoxCategory.setSelection(value);
	}
	public void setParent(Ingredient ingredient){
		if(ingredient == null){
			textParent.setText("");
			return;
		}
		String name = ingredient.getName();
		if( ! name.equals(textParent.getText())){
			textParent.setText(name);
		}		
	}
	public void setCategories(Iterator<String> categories){
		StringBuffer buffer = new StringBuffer();
		while (categories.hasNext()) {
			String category = (String) categories.next();
			buffer.append(category);
			if(categories.hasNext()){
				buffer.append(", ");
			}
		}
		textCategories.setText(buffer.toString());
	}
	
	public Double getPrice(){
		String valueString = textPrice.getText();
		Double result = null;
		try{
			result = Double.parseDouble(valueString);
		}catch(NumberFormatException exc){			
		}
		return result;
	}
	public void setPrice(Double value){
		Double priceAlready = getPrice();
		if(priceAlready != null && priceAlready.equals(value))return;
		Point index = textPrice.getSelection();
		textPrice.setText(value.toString());
		textPrice.setSelection(index); 
	}
	public String getDescription(){
		return textDescription.getText();
	}
	
	public void setDescription(String value){
		if(getDescription().equals(value))return;
		Point selection = textDescription.getSelection();
		textDescription.setText(value);
		textDescription.setSelection(selection); 
	}
	
//	===================
//		Listeners
//	===================
	
	private Collection<ActionListener> isIngredientChangedListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerIsIngredientChangedListener(ActionListener listener){
		return isIngredientChangedListeners.add(listener);
	}
	public boolean deRegisterIsIngredientChangedListener(ActionListener listener){
		return isIngredientChangedListeners.remove(listener);
	}
	private IsIngredientChangedAdvancer isIngredientChanged = new IsIngredientChangedAdvancer();  //  @jve:decl-index=0:
	private class IsIngredientChangedAdvancer extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "IsIngredientChanged");
			for (ActionListener listener : isIngredientChangedListeners) {
				listener.actionPerformed(event);
			}
		}		
	}
	private Collection<ActionListener> isCategoryChangedListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerIsCategoryChangedListener(ActionListener listener){
		return isCategoryChangedListeners.add(listener);
	}
	public boolean deRegisterIsCategoryChangedListener(ActionListener listener){
		return isCategoryChangedListeners.remove(listener);
	}
	private IsCategoryChangedAdvancer isCategoryChanged = new IsCategoryChangedAdvancer();  //  @jve:decl-index=0:
	private class IsCategoryChangedAdvancer extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "IsCategoryChanged");
			for (ActionListener listener : isCategoryChangedListeners) {
				listener.actionPerformed(event);
			}
		}		
	}
	private Collection<ActionListener> removeParentListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerRemoveParentListener(ActionListener listener){
		return removeParentListeners.add(listener);
	}
	public boolean deRegisterRemoveParentListener(ActionListener listener){
		return removeParentListeners.remove(listener);
	}
	private RemoveParentAdvancer removeParent = new RemoveParentAdvancer();  //  @jve:decl-index=0:
	private class RemoveParentAdvancer extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			if(e.keyCode == SWT.DEL){
				ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "RemoveParent");
				for (ActionListener listener : removeParentListeners) {
					listener.actionPerformed(event);
				}
			}
		}			
	}
	private Collection<ActionListener> removeLastCategoryListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerRemoveLastCategoryListener(ActionListener listener){
		return removeLastCategoryListeners.add(listener);
	}
	public boolean deRegisterRemoveLastCategoryListener(ActionListener listener){
		return removeLastCategoryListeners.remove(listener);
	}
	private RemoveLastCategoryAdvancer removeLastCategory = new RemoveLastCategoryAdvancer();  //  @jve:decl-index=0:
	private class RemoveLastCategoryAdvancer extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			if(e.keyCode == SWT.DEL){
				ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "RemoveLastCategory");
				for (ActionListener listener : removeLastCategoryListeners) {
					listener.actionPerformed(event);
				}
			}
		}		
	}
	
	private Collection<ActionListener> nameModifiedListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerNameModifiedListener(ActionListener listener){
		return nameModifiedListeners.add(listener);
	}
	public boolean deRegisterNameModifiedListener(ActionListener listener){
		return nameModifiedListeners.remove(listener);
	}
	private NameModifiedAdvancer nameModified = new NameModifiedAdvancer();  //  @jve:decl-index=0:
	private class NameModifiedAdvancer implements ModifyListener{		
		@Override
		public void modifyText(ModifyEvent e) {
			ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "nameModified");
			for (ActionListener listener : nameModifiedListeners) {
				listener.actionPerformed(event);
			}
			
		}		
	}
	private Collection<ActionListener> descriptionModifiedListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerDescriptionModifiedListener(ActionListener listener){
		return descriptionModifiedListeners.add(listener);
	}
	public boolean deRegisterDescriptionModifiedListener(ActionListener listener){
		return descriptionModifiedListeners.remove(listener);
	}
	private DescriptionModifiedAdvancer descriptionModified = new DescriptionModifiedAdvancer();  //  @jve:decl-index=0:
	private class DescriptionModifiedAdvancer implements ModifyListener{
		@Override
		public void modifyText(ModifyEvent e) { 
			ActionEvent event = new ActionEvent(CompositeIngredient.this, ActionEvent.ACTION_PERFORMED, "DescriptionModified");
			for (ActionListener listener : descriptionModifiedListeners) {
				listener.actionPerformed(event);
			}
		}	
	}
	
	private Collection<ActionListener> priceModifiedListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerPriceModifiedListener(ActionListener listener){
		return priceModifiedListeners.add(listener);
	}
	public boolean deRegisterPriceModifiedListener(ActionListener listener){
		return priceModifiedListeners.remove(listener);
	}

	
	
	
}  //  @jve:decl-index=0:visual-constraint="10,10"
